/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup Audio
 * @{
 *
 * @brief Audio模块接口定义
 *
 * 音频接口涉及自定义类型、驱动加载接口、驱动适配器接口、音频播放（render）接口、音频录音（capture）接口等
 *
 * @since 1.0
 * @version 1.0
 */

/**
 * @file audio_adapter.h
 *
 * @brief Audio适配器的接口定义文件
 *
 * @since 1.0
 * @version 1.0
 */

#ifndef AUDIO_ADAPTER_H
#define AUDIO_ADAPTER_H

#include "audio_types.h"
#include "audio_render.h"
#include "audio_capture.h"

/**
 * @brief AudioAdapter音频适配器接口
 *
 * 提供音频适配器（声卡）对外支持的驱动能力，包括初始化端口、创建render、创建capture、获取端口能力集等
 *
 * @see AudioRender
 * @see AudioCapture
 * @since 1.0
 * @version 1.0
 */
struct AudioAdapter {
    /**
     * @brief 初始化一个音频适配器所有的端口驱动
     *
     * 在音频服务中，调用其他驱动接口前需要首先调用该接口检查端口是否已经初始化完成，如果端口驱动初始化完成，则函数返回值0，
     * 否则返回负值，如果端口没有初始化完成，则需要等待一段时间（例如100ms）后重新进行检查，直到端口初始化完成后再继续操作
     *
     * @param adapter 待操作的音频适配器对象
     * @return 成功返回值0，失败返回负值
    */
    int (*InitAllPorts)(struct AudioAdapter *adapter);

    /**
     * @brief 创建一个音频播放（render）接口的对象
     *
     * @param adapter 待操作的音频适配器对象
     * @param desc 待打开的音频设备描述符
     * @param attrs 待打开的音频采样属性
     * @param render 获取的音频播放接口的对象实例保存到render中
     * @return 成功返回值0，失败返回负值
     * @see GetPortCapability
     * @see DestroyRender
     */
    int32_t (*CreateRender)(struct AudioAdapter *adapter, const struct AudioDeviceDescriptor *desc,
                            const struct AudioSampleAttributes *attrs, struct AudioRender **render);

    /**
     * @brief 销毁一个音频播放（render）接口的对象
     *
     * @attention 在音频播放过程中，不能销毁该接口对象
     *
     * @param adapter 待操作的音频适配器对象
     * @param render 待操作的音频播放接口对象
     * @return 成功返回值0，失败返回负值
     * @see CreateRender
     */
    int32_t (*DestroyRender)(struct AudioAdapter *adapter, struct AudioRender *render);

    /**
     * @brief 创建一个音频录音（capture）接口的对象
     *
     * @param adapter 待操作的音频适配器的指针
     * @param desc 指向要启动的音频适配器的描述符的指针
     * @param attrs 指向要打开的音频采样属性的指针
     * @param capture 指向AudioCapture对象的二级指针
     * @return 成功返回值0，失败返回负值
     * @see GetPortCapability
     * @see DestroyCapture
     */
    int32_t (*CreateCapture)(struct AudioAdapter *adapter, const struct AudioDeviceDescriptor *desc,
                             const struct AudioSampleAttributes *attrs, struct AudioCapture **capture);

    /**
     * @brief 销毁一个音频录音（capture）接口的对象
     *
     * @attention 在音频录音过程中，不能销毁该接口对象
     *
     * @param adapter 待操作的音频适配器对象
     * @param capture 待操作的音频录音接口对象
     * @return 成功返回值0，失败返回负值
     * @see CreateCapture
     */
    int32_t (*DestroyCapture)(struct AudioAdapter *adapter, struct AudioCapture *capture);

    /**
     * @brief 获取一个音频适配器的端口驱动的能力集
     *
     * @param adapter 待操作的音频适配器对象
     * @param port 待获取的端口
     * @param capability 获取的端口能力保存到capability中
     * @return 成功返回值0，失败返回负值
     */
    int (*GetPortCapability)(struct AudioAdapter *adapter, struct AudioPort *port,
                            struct AudioPortCapability *capability);
    /**
     * @brief 设置音频端口驱动的数据透传模式
     *
     * @param adapter 待操作的音频适配器对象
     * @param port 待设置的端口
     * @param mode 待设置的传输模式
     * @return 成功返回值0，失败返回负值
     * @see GetPassthroughMode
     */
    int (*SetPassthroughMode)(struct AudioAdapter *adapter, struct AudioPort *port,
                            enum AudioPortPassthroughMode mode);

    /**
     * @brief 获取音频端口驱动的数据透传模式
     *
     * @param adapter 待操作的音频适配器对象
     * @param port 待获取的端口
     * @param mode 获取的传输模式保存到mode中
     * @return 成功返回值0，失败返回负值
     * @see SetPassthroughMode
     */
    int (*GetPassthroughMode)(struct AudioAdapter *adapter, struct AudioPort *port,
                            enum AudioPortPassthroughMode *mode);

    /**
     * @brief 更新一个或多个发送端和接受端之间的路由
     *
     * @param adapter 待操作的音频适配器对象
     * @param route 路由信息
     * @param routeHandle 生成的路由句柄
     * @return 成功返回值0，失败返回负值
     */
    int32_t (*UpdateAudioRoute)(struct AudioAdapter *adapter, const struct AudioRoute *route, int32_t *routeHandle);

    /**
     * @brief 释放一个音频路由.
     *
     * @param adapter 待操作的音频适配器对象
     * @param routeHandle 待释放的路由句柄.
     * @return 成功返回值0，失败返回负值
     */
    int32_t (*ReleaseAudioRoute)(struct AudioAdapter *adapter, int32_t routeHandle);
};

#endif /* AUDIO_ADAPTER_H */
/** @} */
